#include <iostream>
using namespace std;
#include <set>
#include <string.h>

//set是一个集合容器   //内部红黑树 平衡二叉树 插入和删除操作上比vector快
//set元素是唯一的 自动排序  默认是从小到大排序的
//不能按照[]插入元素

void printS(set<int> &s)
{
        for (set<int>::iterator it = s.begin(); it != s.end(); it++)
        {
                cout<<*it<<" ";
        }
        cout<<endl;
}

void test1()
{
        set<int> set1;
        //默认其实是这样的 谓词 set<int, less<int>> set1;
        
        //插入元素
        for (int i = 0; i < 5; i++)
        {
                int tmp = rand();
                set1.insert(tmp);
        }
        
        //重复插入元素
        set1.insert(100);
        set1.insert(100);
        set1.insert(100);//虽然插入了3个100但是只会有一个

        printS(set1);//默认是从小到大排序的

        //删除集合
        while (!set1.empty())
        {
                set<int>::iterator it = set1.begin();
                cout<<*it<< " ";
                set1.erase(set1.begin());
        }
        cout<<endl;
}

void test2()
{
        //从大到小排列
        set<int,  greater<int>> set1;
        
        for (int i = 0; i < 5; i++)
        {
                int tmp = i+1;
                set1.insert(tmp);
        }

        for (set<int, greater<int>>::iterator it = set1.begin(); it != set1.end(); it++)
        {
                cout<<*it<<" ";
        }
        cout<<endl;
}

//对于自定义的数据类型 Teacher Student set集合是如何排序呢?
class Student
{
public:
        int age;
        char name[64];
public:
        Student(const char *name, int age)
        {
                strcpy(this->name, name);
                this->age = age;
        }
        void printT()
        {
                cout<<"age: "<<age <<endl;
        }
};
//仿函数 用来给用户自定义来排序
struct FuncStudent
{
        bool operator()(const Student &left, const Student &right)
        {
                if(left.age < right.age) //按照年龄从小到大 
                {
                        return true;
                }
                return false;
        }
};

void test3()
{
        set<Student, FuncStudent> set1;
        Student s1("s1", 31);
        Student s2("s2", 22);
        Student s3("s3", 44);
        Student s4("s4", 55);
        Student s5("s5", 55);

        set1.insert(s1);
        set1.insert(s2);
        set1.insert(s3);
        set1.insert(s4);
        set1.insert(s5); //如果两个31岁 能插入成功？ set是唯一集合 是按照name唯一还是age唯一呢?
        //如何知道 插入的结果 看insert函数的返回值

        //遍历
        for(set<Student, FuncStudent>::iterator it = set1.begin(); it != set1.end(); it++)
        {
                cout<<it->age<<" "<<it->name<<endl;
        }
}

//typedef pair<iterator, bool> _Pairib
//如何判断set1.insert()函数的返回值
void test4()
{
        Student s1("s1", 31);
        Student s2("s2", 22);
        Student s3("s3", 44);
        Student s4("s4", 55);
        Student s5("s5", 55);

        set<Student, FuncStudent> set1;
        pair<set<Student, FuncStudent>::iterator, bool>  pair1 = set1.insert(s1);
        if(pair1.second == true)
        {
                cout<<"插入s1成功"<<endl;
        }else{
                cout<<"插入s1失败"<<endl;
        }

        set1.insert(s2);
        pair<set<Student, FuncStudent>::iterator, bool>  pair5 = set1.insert(s5);
        if(pair5.second == true)
        {
                cout<<"插入s5成功"<<endl;
        }else{
                cout<<"插入s5失败"<<endl;
        }

}

//set 查找和删除
//返回结果是pair 就是迭代器的位置
void test5()
{
        set<int> set1;
        for (int i = 0; i < 10; i++)
        {
                set1.insert(i+1);
        }

        for (set<int>::iterator it = set1.begin(); it != set1.end() ; it++)
        {
                cout<<*it<<" ";
        }
        cout<<endl;

        set<int>::iterator it1 = set1.find(5);
        cout<<"it1: "<< *it1 <<endl;

        int num1 = set1.count(5);
        cout<<"num1: "<<num1<<endl;

        set<int>::iterator it2 = set1.lower_bound(5); 
        cout<<"it2: "<<*it2<<endl;

        set<int>::iterator it3 = set1.lower_bound(5); //大于5的元素 的迭代器的位置
        cout<<"it3: "<<*it3<<endl;
        
        //删除元素
        //set1.erase(5);
        pair<set<int>::iterator, set<int>::iterator>  pair1  = set1.equal_range(5);
        cout<<*pair1.first<<" "<<*pair1.second<<endl;

}

int main(int argc, char const *argv[])
{
        //test1();
        //test2();
        //test3();
        //test4();
        test5();
        return 0;
}
